Member location

The member location feature enables you to track where members are within a space, to see which part of your application they’re interacting with. A location could be the form field they have selected, the cell they’re currently editing in a spreadsheet, or the slide they’re viewing within a slide deck. Multiple members can be present in the same location.

Member locations are used to visually display which component other members currently have selected, or are currently active on. Events are emitted whenever a member sets their location, such as when they click on a new cell, or slide. Events are received by members subscribed to location events and the UI component can be highlighted with the active member’s profile data to visually display their location.

Use the set() method to emit a location event in realtime when a member changes their location. This will be received by all location subscribers to inform them of the location change. A location can be any JSON-serializable object, such as a slide number or element ID.

A member must have been entered into the space to set their location.

The set() method is commonly combined with addEventListener() or a React synthetic event, such as onClick or onHover.

The following is an example of a member setting their location to a specific slide number, and element on that slide:

Select...
await space.locations.set({ slide: '3', component: 'slide-title' });
Copied!

Subscribe to location events by registering a listener. Location events are emitted whenever a member changes location by calling set(). Use the subscribe() method on the locations namespace of the space to receive updates.

All location changes are update events. When a location update is received, clear the highlight from the UI component of the member’s previousLocation and add it to currentLocation.

The following is an example of subscribing to location events:

Select...
space.locations.subscribe('update', (locationUpdate) => { console.log(locationUpdate); });
Copied!

The following is an example payload of a location event. Information about location is returned in currentLocation and previousLocation:

{ "member": { "clientId": "clemons#142", "connectionId": "hd9743gjDc", "isConnected": true, "profileData": { "username": "Claire Lemons", "avatar": "https://slides-internal.com/users/clemons.png" }, "location": { "slide": "3", "component": "slide-title" }, "lastEvent": { "name": "update", "timestamp": 1972395669758 } }, "previousLocation": { "slide": "2", "component": null }, "currentLocation": { "slide": "3", "component": "slide-title" } }
Copied!

The following are the properties of a location event payload:

Property Description Type
member.clientId The client identifier for the member. String
member.connectionId The unique identifier of the member’s connection. String
member.isConnected Whether the member is connected to Ably or not. Boolean
member.lastEvent.name The most recent event emitted by the member. Will be one of enter, update, present or leave. String
member.lastEvent.timestamp The timestamp of the most recently emitted event. Number
member.profileData The optional profile data associated with the member. Object
previousLocation The previous location of the member. Object
currentLocation The new location of the member. Object

Unsubscribe from location events to remove previously registered listeners.

The following is an example of removing a listener for location update events:

Select...
space.locations.unsubscribe('update', listener);
Copied!

Or remove all listeners:

Select...
space.locations.unsubscribe();
Copied!

Member locations can also be retrieved in one-off calls. These are local calls and retrieve the location of members retained in memory by the SDK.

The following is an example of retrieving a member’s own location:

Select...
const myLocation = await space.locations.getSelf();
Copied!

The following is an example payload returned by space.locations.getSelf(). It will return the properties of the member’s location:

{ "slide": "3", "component": "slide-title" }
Copied!

The following is an example of retrieving the location objects of all members other than the member themselves.

Select...
const othersLocations = await space.locations.getOthers();
Copied!

The following is an example payload returned by space.locations.getOthers(). It will return the properties of all member’s location by their connectionId:

{ "xG6H3lnrCn": { "slide": "1", "component": "textBox-1" }, "el29SVLktW": { "slide": "1", "component": "image-2" } }
Copied!

The following is an example of retrieving the location objects of all members, including the member themselves:

Select...
const allLocations = await space.locations.getAll();
Copied!

The following is an example payload returned by space.locations.getAll(). It will return the properties of all member’s location by their connectionId:

{ "xG6H3lnrCn": { "slide": "1", "component": "textBox-1" }, "el29SVLktW": { "slide": "1", "component": "image-2" }, "dieF3291kT": { "slide": "3", "component": "slide-title" } }
Copied!

The following is an example of the steps involved in implementing member locations.

Select...
import Spaces from '@ably/spaces'; import { Realtime } from 'ably'; // Import your custom logic for handling member location updates import updateLocations from '/src/own-logic'; // Create an Ably client const client = new Realtime.Promise({ authUrl: '<authEndpoint>', clientId: '<clientId>' }); // Initialize the Spaces SDK using the Ably client const spaces = new Spaces(client); // Create a new space const space = await spaces.get('board-presentation'); // Enter the space to become a member, passing a nickname await space.enter({ name: 'Amelie' }); // Listen to member location updates space.locations.subscribe('update', ({ member, currentLocation, previousLocation }) => { // Update the UI to reflect member locations when receiving an update by adding a highlight to their currentLocation and removing the one from their previousLocation updateLocations(member, currentLocation, previousLocation); }); // Publish the member's location await space.locations.set({ slide: 0, elementId: 'title' });
Copied!

The Spaces SDK is built upon existing Ably functionality available in Ably’s Core SDKs. Understanding which core features are used to provide the abstractions in the Spaces SDK enables you to manage space state and build additional functionality into your application.

Member locations build upon the functionality of the Pub/Sub Channels presence feature. Members are entered into the presence set when they enter the space.

Set member location
v2.0